package com.shuoyue.ycgk.views;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;

import androidx.annotation.Nullable;

import com.shuoyue.ycgk.R;
import com.shuoyue.ycgk.utils.SizeUtil;

public class SportProgressView extends View {
    private static final String TAG = "SportProgressView";

    private Paint mPaint;
    private Paint mTextPaint;

    private int colorStart = Color.parseColor("#49BCCE");
    private int colorEnd = Color.parseColor("#FF6766");
    private int colorEmpty = Color.parseColor("#EAEAEA");

    private int mWidth; // 控件的宽高
    private int mHeight;

    private int margin;
    private int mProgressWidth;
    private int mProgressR;
    private int mStepTextSize;

    private float mCurProgress;

    private String mStartValue = "0%";
    private String mTargetValue = "100%";
    private boolean isShowProgressText = false;
    private boolean isShowProgressTotalText = false;

    private int angle = 360;//默认绘制角度
    private Context mContext;
    int scanStartAngle;

    public SportProgressView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SportProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        initAttr(attrs, defStyleAttr);

        init();
    }

    private void initAttr(AttributeSet attrs, int defStyleAttr) {
        TypedArray a = mContext.getTheme().obtainStyledAttributes(attrs, R.styleable.SportProgressView, defStyleAttr, 0);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.SportProgressView_startColor:
                    colorStart = a.getColor(attr, colorStart);
                    break;
                case R.styleable.SportProgressView_endColor:
                    colorEnd = a.getColor(attr, colorEnd);
                    break;
                case R.styleable.SportProgressView_emptyColor:
                    colorEmpty = a.getColor(attr, colorEmpty);
                    break;
                case R.styleable.SportProgressView_progressWidth:
                    mProgressWidth = a.getDimensionPixelSize(attr, 14);
                    break;
                case R.styleable.SportProgressView_stepTextSize:
                    mStepTextSize = a.getDimensionPixelSize(attr, 10);
                    break;
                case R.styleable.SportProgressView_isShowProgressText:
                    isShowProgressText = a.getBoolean(attr, false);
                    break;
                case R.styleable.SportProgressView_isShowProgressTotalText:
                    isShowProgressTotalText = a.getBoolean(attr, false);
                    break;
                case R.styleable.SportProgressView_angle:
                    angle = a.getInt(attr, 360);
                    break;
                default:
                    break;
            }
        }
        a.recycle();
    }

    /**
     * 初始化
     */
    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStrokeWidth(mProgressWidth);
        mPaint.setStyle(Paint.Style.STROKE);

        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setColor(colorEmpty);
        mTextPaint.setTextSize(mStepTextSize);

        margin = SizeUtil.dip2px(mContext, 8);
        scanStartAngle = (360 - angle) / 2 + 90;
    }

    float cosX = 0;

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

        if (widthSpecMode == MeasureSpec.EXACTLY) {
            mWidth = widthSpecSize;
        } else if (widthSpecMode == MeasureSpec.AT_MOST) {
            mWidth = 500;
        }

        if (heightSpecMode == MeasureSpec.EXACTLY) {
            mHeight = heightSpecSize;
        } else if (widthSpecMode == MeasureSpec.AT_MOST) {
            mHeight = 500;
        }
        mWidth = mWidth > mHeight ? mHeight : mWidth;//取小
        mHeight = mWidth > mHeight ? mHeight : mWidth;//取小

        //cos角度
        double alp = (360d - angle) / 2d;
        if (alp > 90) {
            alp = 180 - alp;
        }
        /**
         * 以给定的高度为限制条件，计算半径
         */
        cosX = (float) Math.cos(alp);
        mProgressR = (int) ((mHeight - margin - mProgressWidth) / (Math.abs(cosX) + 1));
        if (mProgressR > mWidth / 2 - mProgressWidth / 2 - margin - (isShowProgressTotalText ? getTextHeight(mTextPaint) / 2 : 0)) {
            mProgressR = mWidth / 2 - mProgressWidth / 2 - margin - (isShowProgressTotalText ? getTextHeight(mTextPaint) / 2 : 0);
        }
        Log.i(TAG, "onMeasure--->mWidth = " + mWidth + ",mHeight = " + mHeight);
        setMeasuredDimension(mWidth, mHeight);
    }

    private float mProgress;

    @Override
    protected void onDraw(Canvas canvas) {
        Log.i(TAG, "onDraw--->");
        int left = mWidth / 2 - mProgressR;

        int right = left + 2 * mProgressR;
        int top = (int) (mProgressWidth / 2
                + margin
//               - (isShowProgressTotalText ? getTextHeight(mTextPaint) : 0)
                + (mProgressR - (Math.abs(cosX) * mProgressR)));
        int bottom = top + mProgressR * 2;
        RectF rect = new RectF(left, top, right, bottom);

        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setColor(colorEmpty);
        mPaint.setShader(null);
        canvas.drawArc(rect, scanStartAngle, angle, false, mPaint);
        /**
         * 设置渐变颜色
         */
        int[] colors = new int[]{colorStart, colorEnd};
        LinearGradient linearGradient = new LinearGradient(0, 0, mWidth, 0, colors,
                null, LinearGradient.TileMode.CLAMP);
        mPaint.setShader(linearGradient);
        canvas.drawArc(rect, scanStartAngle, mProgress, false, mPaint);

        if (isShowProgressText) {
//            drawText(canvas);
            drawProgressText(canvas, mProgress);
        }
        if (isShowProgressTotalText) {
            drawText(canvas);
        }

    }

    /**
     * 画底部初始的文字和结束的文字
     *
     * @param canvas
     */
    private void drawText(Canvas canvas) {
        mTextPaint.setColor(colorEmpty);
        mTextPaint.setTextSize(mStepTextSize);
        Paint.FontMetrics fm = mTextPaint.getFontMetrics();
        float baseline = mHeight - fm.descent - margin;
        float stringWidth = mTextPaint.measureText(mStartValue);
        float startX = getPaddingLeft() - stringWidth / 2 + mProgressWidth / 2;
        canvas.drawText(mStartValue, startX < 10 ? 10 : startX, baseline, mTextPaint);

        stringWidth = mTextPaint.measureText(mTargetValue);
        float startY = mWidth - getPaddingRight() - stringWidth + stringWidth / 2 - mProgressWidth / 2;
        canvas.drawText(mTargetValue, startY + stringWidth > mWidth - 10 ? mWidth - 10 : startY, baseline, mTextPaint);
    }

    /**
     * 绘制中间进度的文字
     *
     * @param canvas
     * @param progress
     */
    private void drawProgressText(Canvas canvas, float progress) {
        Log.i(TAG, "progress = " + progress);
        mTextPaint.setColor(colorStart);
        mTextPaint.setTextSize(mStepTextSize);
        int progressText = (int) (progress / (float) angle * 100f);
        if (progress < 0.01 && progress > 0) {
            progressText = 1;
        }

        String text = progressText + "%";
        Paint.FontMetrics fm = mTextPaint.getFontMetrics();
        float baseline = mHeight / 2 + margin - fm.descent + (mProgressR - (Math.abs(cosX) * mProgressR));
        float stringWidth = mTextPaint.measureText(text);
        canvas.drawText(text, mWidth / 2 - stringWidth / 2, baseline, mTextPaint);
    }


    private int getTextHeight(Paint mTextPaint) {
        Paint.FontMetrics fm = mTextPaint.getFontMetrics();
        int textHeight = (int) (Math.ceil(fm.descent - fm.ascent) + 2);
        return textHeight;
    }

    public void setProgress(float progress) {
        mCurProgress = progress;
        startAnimation();
    }

    public void setProgress(int progress) {
        mCurProgress = progress;
        startAnimation();
    }

    /**
     * 动画效果的取值
     */
    public void startAnimation() {
        mProgress = 0f;
        ValueAnimator animator = ValueAnimator.ofFloat(0, mCurProgress / 100f * angle);
        animator.setDuration(1600).start();
        animator.setInterpolator(new AccelerateInterpolator());
        animator.addUpdateListener(animation -> {
            mProgress = (float) animation.getAnimatedValue();
            invalidate();
        });
    }
}